//
// Created by Hoyin on 2024/1/25.
//

#ifndef VISUAL_LOCATION_UTILS_H
#define VISUAL_LOCATION_UTILS_H

#include <opencv2/opencv.hpp>
#include <iostream>
#include <fstream>
#include "rapidjson/document.h"
#include <Eigen/Core>
#include <random>

namespace utl {
	typedef enum { TOP_LEFT=0, TOP_RIGHT=1, BOTTOM_LEFT=2, BOTTOM_RIGHT=3 } TextAnchor;

	inline float getScale(int level, int firstLevel, float scaleFactor) {
		return (float) pow(scaleFactor, (level - firstLevel));
	}

	void showImage(const char winName[], cv::Mat image, int delay=0);

	void showImages(const std::string& winNamePrefix, std::vector<cv::Mat> images, int delay=0);

	void getBitPattern(const char* bitPatternFile, int bitPattern[]);

	inline void makeRandomPattern(int patchSize, cv::Point* pattern, int npoints)
	{
		cv::RNG rng(0x34985739); // we always start with a fixed seed,
		// to make patterns the same on each run
		for( int i = 0; i < npoints; i++ )
		{
			pattern[i].x = rng.uniform(-patchSize/2, patchSize/2+1);
			pattern[i].y = rng.uniform(-patchSize/2, patchSize/2+1);
		}
	}

	void initializeOrbPattern(const cv::Point* pattern0, std::vector<cv::Point>& pattern, int ntuples, int tupleSize, int poolSize);

	void ransac(std::vector<cv::DMatch> matches, std::vector<cv::KeyPoint> queryKeyPoint, std::vector<cv::KeyPoint> trainKeyPoint, std::vector<cv::DMatch> &matches_ransac);

	std::stringstream readFile(const std::string &file);

	void drawBarChart(Eigen::VectorXi &vec, cv::Mat &dst);

	inline cv::Scalar randColor() {
		std::random_device rd;
		std::default_random_engine e(rd());
		std::uniform_int_distribution<int> dist(0, 255);
		cv::Scalar color(dist(e), dist(e), dist(e));
		return color;
	}

	void drawText(const std::string& text, cv::Mat &canvas, const cv::Point &pos, const cv::Scalar &color, cv::Scalar &fillColor, double fontScale, int anchor=0);
}


#endif //VISUAL_LOCATION_UTILS_H
